home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Tool Chest / QuickDraw GX / QuickDraw GX Info / QuickDraw GX Interfaces / Interfaces & Libraries / graphics libraries / offscreen library.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-30  |  10.7 KB  |  360 lines  |  [TEXT/MPS ]

  1. /* graphics libraries:
  2.     offscreen support library
  3.     by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink, Chris Yerga
  4.     Copyright 1987 - 1991 Apple Computer, Inc.  All rights reserved. */
  5.  
  6.     #include <Memory.h>
  7. #include "graphics libraries.h"
  8. #include "offscreen library.h"
  9.  
  10. typedef struct viewPortBufferRecord {
  11.     gxViewPort    masterPort;
  12.     gxViewPort    slavePort;
  13.     gxShape        area;
  14.     gxShape        draw;
  15.     gxViewGroup    group;
  16.     long            deviceCount;
  17.     gxViewDevice    devices[1];
  18. } viewPortBufferRecord;
  19.  
  20. static void ClearBytes(void *block, register long length)
  21. {
  22.     register char *b = (char *) block;
  23.     
  24.     do
  25.         *b++ = 0;
  26.     while (--length);
  27. }
  28.  
  29. /*
  30.     Given a gxBitmap gxShape, this routine fills out the offscreen structure with the objects necessary to draw into
  31.     the offscreen and transfer the offscreen onscreen.  See the header file for details about the offscreen structure.
  32. */
  33. void CreateOffscreen(register offscreen *os, gxShape bitShape)
  34. {
  35.     NilParamReturn(os);
  36.     ClearBytes(os, sizeof(offscreen));
  37.     NilShapeReturn(bitShape);
  38.     os->group = GXNewViewGroup();
  39.     os->device = GXNewViewDevice(os->group, bitShape);
  40.     os->port = GXNewViewPort(os->group);
  41.     os->draw = GXGetViewDeviceBitmap(os->device);        /* draw this gxShape to copy the offscreen to the screen */
  42.     os->xform = GXNewTransform();                /* assign this to shapes and they will draw offscreen */
  43.     GXSetTransformViewPorts(os->xform, 1, &os->port);
  44. }
  45.  
  46.  
  47. /*
  48.     When you're done with the offscreen, call this routine.
  49. */
  50. void DisposeOffscreen(offscreen *os)
  51. {
  52.     NilParamReturn(os);
  53.     GXDisposeShape(os->draw);        /* dispense with gxBitmap gxShape */
  54.     GXDisposeTransform(os->xform);    /* …and gxTransform */
  55.     GXDisposeViewGroup(os->group);    /* …and gxViewGroup (which disposes gxViewPort and gxViewDevice) */
  56. }
  57.  
  58.  
  59. void CopyToBitmaps(gxShape dest, gxShape source)
  60. {
  61.     offscreen destOff;
  62.     
  63.     NilShapeReturn(dest);
  64.     NilShapeReturn(source);
  65.     CreateOffscreen(&destOff, dest);
  66.     {    long portCount = GXGetShapeViewPorts(source, nil);
  67.         gxViewPort *savedPorts = (gxViewPort *) NewPtr(sizeof(gxViewPort) * portCount);
  68.         
  69.         GXGetShapeViewPorts(source, savedPorts);
  70.         GXSetShapeViewPorts(source, 1, &destOff.port);
  71.         GXDrawShape(source);
  72.         GXSetShapeViewPorts(source, portCount, savedPorts);
  73.         DisposePtr((Ptr) savedPorts);
  74.     }
  75.     DisposeOffscreen(&destOff);
  76. }
  77.  
  78. typedef struct {
  79.     gxBitmap    bits;
  80.     gxPoint        offset;
  81. } areaCharacteristics;
  82.  
  83. static areaCharacteristics GetAreaCharacteristics(gxShape area, gxViewDevice device, gxViewPort port)
  84. {
  85.     areaCharacteristics x;
  86.     gxRectangle bounds;
  87.     gxShape bitShape;
  88.     gxMapping map;
  89.  
  90.     ClearBytes(&x, sizeof(x));
  91.     ClearBytes(&bounds, sizeof(bounds));
  92.     ClearBytes(&map, sizeof(map));
  93.     bitShape = GXGetViewDeviceBitmap(device);
  94.     GXGetShapeGlobalBounds(area, port, nil, &bounds);
  95.     GXGetBitmap(bitShape, &x.bits, nil);
  96.     if (x.bits.space == gxIndexedSpace)
  97.         GXCloneColorSet(x.bits.set);
  98.     if (x.bits.profile)
  99.         GXCloneColorProfile(x.bits.profile);
  100.     GXDisposeShape(bitShape);
  101.     x.offset.x = bounds.left;
  102.     x.offset.y = bounds.top;
  103.     x.bits.width = FixedRound(bounds.right) - FixedRound(bounds.left);
  104.     x.bits.height = FixedRound(bounds.bottom) - FixedRound(bounds.top);
  105.     InvertMapping(&map, GXGetViewPortGlobalMapping(port, &map));
  106.     MapPoints(&map, 1, &x.offset);
  107.     return x;
  108. }
  109.  
  110. static void DisposeAreaCharacteristics(areaCharacteristics *x)
  111. {
  112.     if (x->bits.space == gxIndexedSpace)
  113.         GXDisposeColorSet(x->bits.set);
  114.     if (x->bits.profile)
  115.         GXDisposeColorProfile(x->bits.profile);
  116. }
  117.  
  118. static gxViewDevice NewDeviceWithAreaCharacteristics(gxViewGroup group, areaCharacteristics *x)
  119. {
  120.     gxViewDevice device;
  121.     gxShape bitShape;
  122.     gxMapping map;
  123.  
  124.     NilParamReturnNil(x);
  125.     bitShape = GXNewBitmap(&x->bits, nil);
  126.     device = GXNewViewDevice(group, bitShape);
  127.     GXDisposeShape(bitShape);
  128.     ResetMapping(&map);
  129.     MoveMapping(&map, -x->offset.x, -x->offset.y);
  130.     GXSetViewDeviceMapping(device, &map);
  131.     return device;
  132. }
  133.  
  134. static areaCharacteristics GetDeviceAreaCharacteristics(gxViewDevice device)
  135. {
  136.     areaCharacteristics x;
  137.     gxShape bitShape;
  138.     gxMapping map;
  139.  
  140.     ClearBytes(&x, sizeof(x));
  141.     ClearBytes(&map, sizeof(map));
  142.     bitShape = GXGetViewDeviceBitmap(device);
  143.     GXGetBitmap(bitShape, &x.bits, nil);
  144.     if (x.bits.space == gxIndexedSpace)
  145.         GXCloneColorSet(x.bits.set);
  146.     if (x.bits.profile)
  147.         GXCloneColorProfile(x.bits.profile);
  148.     GXDisposeShape(bitShape);
  149.     GXGetViewDeviceMapping(device, &map);
  150.     x.offset.x = -map.map[2][0];
  151.     x.offset.y = -map.map[2][1];
  152.     return x;
  153. }
  154.  
  155. static void SetDeviceAreaCharacteristics(gxViewDevice device, areaCharacteristics *x)
  156. {
  157.     gxShape bitShape;
  158.     gxBitmap bits;
  159.     gxMapping map;
  160.  
  161.     NilParamReturn(x);
  162.     bits.width = 1;
  163.     bits.height = 1;
  164.     bits.pixelSize = 1;
  165.     bits.rowBytes = 0;
  166.     bits.image = nil;
  167.     bits.space = gxIndexedSpace;
  168.     bits.set = nil;
  169.     bits.profile = nil;
  170.     bitShape = GXNewBitmap(&bits, nil);
  171.     GXSetViewDeviceBitmap(device, bitShape);
  172.     GXDisposeShape(bitShape);
  173.  
  174.     bitShape = GXNewBitmap(&x->bits, nil);
  175.     GXSetViewDeviceBitmap(device, bitShape);
  176.     GXDisposeShape(bitShape);
  177.     ResetMapping(&map);
  178.     MoveMapping(&map, -x->offset.x, -x->offset.y);
  179.     GXSetViewDeviceMapping(device, &map);
  180. }
  181.  
  182. static boolean EqualAreaCharacteristics(areaCharacteristics *x, areaCharacteristics *y)
  183. {
  184.     NilParamReturnNil(x);
  185.     NilParamReturnNil(y);
  186.     return x->bits.space == y->bits.space
  187.         && x->bits.set == y->bits.set
  188.         && x->bits.profile == y->bits.profile
  189.         && x->offset.x == y->offset.x
  190.         && x->offset.y == y->offset.y
  191.         && x->bits.width == y->bits.width
  192.         && x->bits.height == y->bits.height
  193.         && x->bits.pixelSize == y->bits.pixelSize;
  194. }
  195.  
  196. static void AddBitmapShapes(viewPortBufferRecord *buffers)
  197. {
  198.     short i;
  199.  
  200.     NilParamReturn(buffers);
  201.     for (i = 0; i < buffers->deviceCount; i++) 
  202.     {    gxViewDevice device = buffers->devices[i];
  203.         gxShape bitShape = GXGetViewDeviceBitmap(device);
  204.         gxMapping map;
  205.     
  206.         ClearBytes(&map, sizeof(map));
  207.         GXGetViewDeviceMapping(device, &map);
  208.         GXSetShapeAttributes(bitShape, GXGetShapeAttributes(bitShape) | gxMapTransformShape);
  209.         GXMoveShape(bitShape, -map.map[2][0], -map.map[2][1]);
  210.         GXSetShapeParts(buffers->draw, 0, 0, bitShape, 0);
  211.         GXDisposeShape(bitShape);
  212.     }
  213. }
  214.  
  215. viewPortBuffer NewViewPortBuffer(gxViewPort port)
  216. {
  217.     viewPortBuffer buffersHandle;
  218.     viewPortBufferRecord *buffers;
  219.     gxTransform xform;
  220.     gxShape area;
  221.     long deviceCount;
  222.     short i;
  223.  
  224.     NilParamReturnNil(port);
  225.     area = GXNewShape(gxFullType);
  226.     xform = GXNewTransform();
  227.     GXSetTransformViewPorts(xform, 1, &port);
  228.     GXSetShapeTransform(area, xform);
  229.     GXDisposeTransform(xform);
  230.     deviceCount = GXGetShapeGlobalViewDevices(area, port, nil);
  231.     buffersHandle = (viewPortBuffer) NewHandle(sizeof(viewPortBufferRecord) + (deviceCount - 1) * sizeof(gxViewDevice));
  232.     NilParamReturnNil(buffersHandle);
  233.     HLock((Handle) buffersHandle);
  234.     buffers = *buffersHandle;
  235.     buffers->group = GXNewViewGroup();
  236.     buffers->masterPort = port;
  237.     buffers->slavePort = GXNewViewPort(buffers->group);
  238.     buffers->area = area;
  239.     buffers->draw = GXNewShape(gxPictureType);
  240.     buffers->deviceCount = deviceCount;
  241.     GXSetViewPortDither(buffers->slavePort, GXGetViewPortDither(port));
  242.     GXGetShapeGlobalViewDevices(area, port, buffers->devices);
  243.     for (i = 0; i < deviceCount; i++) 
  244.     {    gxViewDevice device = buffers->devices[i];
  245.         areaCharacteristics x = GetAreaCharacteristics(area, device, port);
  246.     
  247.         buffers->devices[i] = NewDeviceWithAreaCharacteristics(buffers->group, &x);
  248.         DisposeAreaCharacteristics(&x);
  249.     }
  250.     AddBitmapShapes(buffers);
  251.     HUnlock((Handle) buffersHandle);
  252.     return buffersHandle;
  253. }
  254.  
  255. void DisposeViewPortBuffer(viewPortBuffer buffersHandle)
  256. {
  257.     NilParamReturn(buffersHandle);
  258.     GXDisposeShape((*buffersHandle)->area);
  259.     GXDisposeShape((*buffersHandle)->draw);
  260.     GXDisposeViewGroup((*buffersHandle)->group);
  261.     DisposeHandle((Handle) buffersHandle);
  262. }
  263.  
  264. boolean ValidViewPortBuffer(viewPortBuffer buffersHandle)
  265. {
  266.     long deviceCount;
  267.     gxViewDevice *devices;
  268.     boolean valid = true;
  269.     short i;
  270.  
  271.     NilParamReturnNil(buffersHandle);
  272.     deviceCount = GXGetShapeGlobalViewDevices((*buffersHandle)->area, (*buffersHandle)->masterPort, nil);
  273.     if (deviceCount != (*buffersHandle)->deviceCount)
  274.         return false;
  275.     devices = (gxViewDevice *) NewPtr(deviceCount * sizeof(gxViewDevice));
  276.     NilParamReturnNil(devices);
  277.     for (i = 0; i < deviceCount; i++) 
  278.     {    areaCharacteristics x = GetAreaCharacteristics((*buffersHandle)->area, devices[i], (*buffersHandle)->masterPort);
  279.         areaCharacteristics y = GetDeviceAreaCharacteristics((*buffersHandle)->devices[i]);
  280.     
  281.         valid = EqualAreaCharacteristics(&x, &y);
  282.         DisposeAreaCharacteristics(&x);
  283.         DisposeAreaCharacteristics(&y);
  284.         if (!valid) break;
  285.     }
  286.     DisposePtr((Ptr) devices);
  287.     return valid;
  288. }
  289.  
  290. boolean UpdateViewPortBuffer(viewPortBuffer buffersHandle)
  291. {
  292.     viewPortBufferRecord *buffers;
  293.     short state;
  294.     long deviceCount;
  295.     gxViewDevice *devices;
  296.     boolean valid = true;
  297.     short i;
  298.  
  299.     NilParamReturnNil(buffersHandle);
  300.     state = HGetState((Handle) buffersHandle);
  301.     HLock((Handle) buffersHandle);
  302.     buffers = *buffersHandle;
  303.     deviceCount = GXGetShapeGlobalViewDevices(buffers->area, buffers->masterPort, nil);
  304.     if (deviceCount != buffers->deviceCount) {
  305.         valid = false;
  306.         GXSetPicture(buffers->draw, 0, nil, nil, nil, nil);
  307.         if (deviceCount < buffers->deviceCount) {
  308.             for (i = deviceCount; i < buffers->deviceCount; i++)
  309.                 GXDisposeViewDevice(buffers->devices[i]);
  310.             SetHandleSize((Handle) buffersHandle, sizeof(viewPortBufferRecord) + (deviceCount - 1) * sizeof(gxViewDevice));
  311.             buffers = *buffersHandle;
  312.         } else {
  313.             HUnlock((Handle) buffersHandle);
  314.             SetHandleSize((Handle) buffersHandle, sizeof(viewPortBufferRecord) + (deviceCount - 1) * sizeof(gxViewDevice));
  315.             HLock((Handle) buffersHandle);
  316.             buffers = *buffersHandle;
  317.             for (i = buffers->deviceCount; i < deviceCount; i++)
  318.                 buffers->devices[i] = nil;
  319.         }
  320.         buffers->deviceCount = deviceCount;
  321.     }
  322.     devices = (gxViewDevice *) NewPtr(deviceCount * sizeof(gxViewDevice));
  323.     NilParamReturnNil(devices);
  324.     deviceCount = GXGetShapeGlobalViewDevices(buffers->area, buffers->masterPort, devices);
  325.     for (i = 0; i < deviceCount; i++) 
  326.     {    gxViewDevice device = buffers->devices[i];
  327.         areaCharacteristics x = GetAreaCharacteristics(buffers->area, devices[i], buffers->masterPort);
  328.     
  329.         if (device) 
  330.         {    areaCharacteristics y = GetDeviceAreaCharacteristics(device);
  331.         
  332.             if (EqualAreaCharacteristics(&x, &y) == false) {
  333.                 valid = false;
  334.                 GXSetPicture(buffers->draw, 0, nil, nil, nil, nil);
  335.                 SetDeviceAreaCharacteristics(device, &x);
  336.             }
  337.             DisposeAreaCharacteristics(&y);
  338.         } else
  339.             buffers->devices[i] = NewDeviceWithAreaCharacteristics(buffers->group, &x);
  340.         DisposeAreaCharacteristics(&x);
  341.     }
  342.     DisposePtr((Ptr) devices);
  343.     if (valid == false)
  344.         AddBitmapShapes(buffers);
  345.     HSetState((Handle) buffersHandle, state);
  346.     return valid;
  347. }
  348.  
  349. gxViewPort GetViewPortBufferViewPort(viewPortBuffer buffersHandle)
  350. {
  351.     NilParamReturnNil(buffersHandle);
  352.     return (*buffersHandle)->slavePort;
  353. }
  354.  
  355. gxShape GetViewPortBufferShape(viewPortBuffer buffersHandle)
  356. {
  357.     NilParamReturnNil(buffersHandle);
  358.     return (*buffersHandle)->draw;
  359. }
  360.